// 日志管理工具 - Vue3兼容版本
class Logger {
  constructor() {
    this.logs = []
    this.maxLogs = 1000 // 最大保存日志数量
    this.originalConsole = {
      log: console.log.bind(console),
      // warn: console.warn.bind(console),
      error: console.error.bind(console),
      info: console.info.bind(console),
      debug: console.debug.bind(console)
    }
    this.init()
  }

  init() {
    // 拦截console方法
    this.interceptConsole()
    // 监听未捕获的错误
    this.listenToErrors()
  }

  // 安全的对象转字符串方法
  safeStringify(obj) {
    if (obj === null) return 'null'
    if (obj === undefined) return 'undefined'
    if (typeof obj === 'string') return obj
    if (typeof obj === 'number' || typeof obj === 'boolean') return String(obj)
    if (typeof obj === 'function') return obj.toString()

    try {
      // 处理循环引用
      const seen = new WeakSet()
      return JSON.stringify(
        obj,
        (key, value) => {
          if (typeof value === 'object' && value !== null) {
            if (seen.has(value)) {
              return '[Circular Reference]'
            }
            seen.add(value)
          }
          return value
        },
        2
      )
    } catch (e) {
      // 如果JSON.stringify失败，尝试其他方法
      try {
        return Object.prototype.toString.call(obj)
      } catch (e2) {
        return '[Object]'
      }
    }
  }

  interceptConsole() {
    const self = this

    // 拦截console.log
    console.log = function (...args) {
      self.addLog('log', args)
      self.originalConsole.log(...args)
    }

    // 拦截console.warn
    // console.warn = function (...args) {
    //   self.addLog('warn', args)
    //   self.originalConsole.warn(...args)
    // }

    // 拦截console.error
    console.error = function (...args) {
      self.addLog('error', args)
      self.originalConsole.error(...args)
    }

    // 拦截console.info
    console.info = function (...args) {
      self.addLog('info', args)
      self.originalConsole.info(...args)
    }

    // 拦截console.debug
    console.debug = function (...args) {
      self.addLog('debug', args)
      self.originalConsole.debug(...args)
    }
  }

  listenToErrors() {
    // 监听未捕获的JavaScript错误
    window.addEventListener('error', (event) => {
      this.addLog('error', [
        `Uncaught Error: ${event.message}`,
        `File: ${event.filename}:${event.lineno}:${event.colno}`,
        `Stack: ${event.error?.stack || 'No stack trace'}`
      ])
    })

    // 监听未处理的Promise拒绝
    window.addEventListener('unhandledrejection', (event) => {
      this.addLog('error', [
        `Unhandled Promise Rejection: ${event.reason}`,
        `Stack: ${event.reason?.stack || 'No stack trace'}`
      ])
    })
  }

  addLog(level, args) {
    const timestamp = new Date().toISOString()

    // 安全地处理参数
    const message = args.map((arg) => this.safeStringify(arg)).join(' ')

    const logEntry = {
      timestamp,
      level,
      message,
      url: window.location.href,
      userAgent: navigator.userAgent
    }

    this.logs.push(logEntry)

    // 限制日志数量，避免内存溢出
    if (this.logs.length > this.maxLogs) {
      this.logs.shift()
    }

    // 存储到localStorage（可选）
    this.saveToStorage()
  }

  saveToStorage() {
    try {
      const recentLogs = this.logs.slice(-100) // 只保存最近100条到localStorage
      localStorage.setItem('app_logs', JSON.stringify(recentLogs))
    } catch (e) {
      // localStorage可能已满，忽略错误
      console.warn('Failed to save logs to localStorage:', e)
    }
  }

  loadFromStorage() {
    try {
      const storedLogs = localStorage.getItem('app_logs')
      if (storedLogs) {
        const logs = JSON.parse(storedLogs)
        this.logs = [...logs, ...this.logs]
      }
    } catch (e) {
      // 忽略解析错误
      console.warn('Failed to load logs from localStorage:', e)
    }
  }

  getLogs(level = null, limit = null) {
    let filteredLogs = this.logs

    if (level) {
      filteredLogs = this.logs.filter((log) => log.level === level)
    }

    if (limit) {
      filteredLogs = filteredLogs.slice(-limit)
    }

    return filteredLogs
  }

  clearLogs() {
    this.logs = []
    try {
      localStorage.removeItem('app_logs')
    } catch (e) {
      console.warn('Failed to clear logs from localStorage:', e)
    }
  }

  exportLogs(filename = null) {
    const timestamp = new Date().toISOString().replace(/[:.]/g, '-')
    const defaultFilename = `app-logs-${timestamp}.json`
    const finalFilename = filename || defaultFilename

    const exportData = {
      exportTime: new Date().toISOString(),
      appInfo: {
        url: window.location.href,
        userAgent: navigator.userAgent,
        timestamp: timestamp
      },
      logs: this.logs
    }

    try {
      const dataStr = JSON.stringify(exportData, null, 2)
      const dataBlob = new Blob([dataStr], { type: 'application/json' })

      const link = document.createElement('a')
      link.href = URL.createObjectURL(dataBlob)
      link.download = finalFilename
      document.body.appendChild(link)
      link.click()
      document.body.removeChild(link)
      URL.revokeObjectURL(link.href)
    } catch (e) {
      console.error('Failed to export logs:', e)
      alert('导出日志失败，请检查控制台错误信息')
    }
  }

  exportLogsAsText(filename = null) {
    const timestamp = new Date().toISOString().replace(/[:.]/g, '-')
    const defaultFilename = `app-logs-${timestamp}.txt`
    const finalFilename = filename || defaultFilename

    let content = `应用日志导出\n`
    content += `导出时间: ${new Date().toISOString()}\n`
    content += `页面URL: ${window.location.href}\n`
    content += `用户代理: ${navigator.userAgent}\n`
    content += `总日志数: ${this.logs.length}\n`
    content += `${'='.repeat(80)}\n\n`

    this.logs.forEach((log, index) => {
      content += `[${index + 1}] ${log.timestamp} [${log.level.toUpperCase()}]\n`
      content += `${log.message}\n`
      if (log.url !== window.location.href) {
        content += `URL: ${log.url}\n`
      }
      content += `${'-'.repeat(40)}\n`
    })

    try {
      const dataBlob = new Blob([content], { type: 'text/plain;charset=utf-8' })

      const link = document.createElement('a')
      link.href = URL.createObjectURL(dataBlob)
      link.download = finalFilename
      document.body.appendChild(link)
      link.click()
      document.body.removeChild(link)
      URL.revokeObjectURL(link.href)
    } catch (e) {
      console.error('Failed to export logs as text:', e)
      alert('导出文本日志失败，请检查控制台错误信息')
    }
  }

  // 获取日志统计信息
  getLogStats() {
    const stats = {
      total: this.logs.length,
      byLevel: {},
      timeRange: null
    }

    this.logs.forEach((log) => {
      stats.byLevel[log.level] = (stats.byLevel[log.level] || 0) + 1
    })

    if (this.logs.length > 0) {
      stats.timeRange = {
        start: this.logs[0].timestamp,
        end: this.logs[this.logs.length - 1].timestamp
      }
    }

    return stats
  }

  // 恢复原始console方法
  restore() {
    console.log = this.originalConsole.log
    // console.warn = this.originalConsole.warn
    console.error = this.originalConsole.error
    console.info = this.originalConsole.info
    console.debug = this.originalConsole.debug
  }
}

// 创建全局实例
const logger = new Logger()

// 导出实例和类
export default logger
export { Logger }
